<template>
  <div class="table-tempalte">
    <slot />
  </div>
</template>
<script>
import { getTableWidth } from './util'

export default {
  name: 'TableTemplate',

  props: {
    commit: Function
  },

  data() {
    return {
      // 所有列的最大depth
      maxDepth: 0,
      // 每一列的最大depth
      colDepthData: {},
      // 基本结构
      structure: [],
      // 底层数据渲染的真实数据（包括slot）
      bottomList: []
    }
  },

  mounted() {
    this.init()
    this.observer = new MutationObserver(() => {
      this.init()
    })
    this.observer.observe(this.$el, {
      attributes: true,
      childList: true,
      characterData: true,
      subtree: true
    })
  },

  methods: {
    init() {
      const structure = []
      this.makeTree(this.$slots.default, structure)
      this.maxDepth = this.analysis(structure, 0).maxDepth
      this.colDepthData = this.colDepth(structure)
      this.nodeSpan(structure)
      this.rowSpan(structure, this.maxDepth)
      this.structure = structure
      this.bottomList = this.getBottomList(structure)
      this.commit({
        maxDepth: this.maxDepth,
        structure: this.structure,
        bottomList: this.bottomList,
        tableWidth: getTableWidth(this.bottomList)
      })
    },
    /*
      + 构成一个Tree
    */
    makeTree(children = [], structure = [], parentNode = {}) {
      for (let i = 0, len = children.length; i < len; i++) {
        const options = children[i].componentOptions
        if (!options) continue
        const id = Object.keys(parentNode).length > 0 ? parentNode.id + '_' + i : i
        const currentNode = {
          id: id,
          width: children[i].width ? children[i].width : 150,
          ...children[i].data.attrs
        }
        if (Object.keys(parentNode).length === 0) {
          structure.push(currentNode)
        } else {
          if (parentNode.children && parentNode.children.length > 0) {
            parentNode.children.push(currentNode)
          } else {
            parentNode.children = [currentNode]
          }
        }
        if (options.children) {
          this.makeTree(options.children, structure, currentNode)
        }
        if (children[i].data.scopedSlots) {
          currentNode.slot = children[i]
        }
      }
    },

    /*
     + 获取最大的层级
     + 给每层打上当前所处的层级
    */
    analysis(structure = [], parentDepth = 0, parentCol = 0, treeDesc = { maxDepth: 0 }) {
      for (let i = 0, len = structure.length; i < len; i++) {
        const current = structure[i]
        current.depth = parentDepth + 1
        current.col = parentCol + i + 1

        if (current.depth > treeDesc.maxDepth) {
          treeDesc.maxDepth = current.depth
        }
        if (current.children) {
          this.analysis(
            current.children,
            current.depth,
            current.col - 1 >= 0 ? current.col - 1 : 0,
            treeDesc
          )
        }
      }
      return treeDesc
    },

    /*
      + 每一列的最大层级
    */
    colDepth(structure = [], treeDepth = {}) {
      for (let i = 0, len = structure.length; i < len; i++) {
        const current = structure[i]
        if (current.children) {
          treeDepth[i] = this.getColMaxDepth(current.children).maxDepth
        } else {
          treeDepth[i] = 1
        }
      }
      return treeDepth
    },

    getColMaxDepth(nodeList = [], depthDesc = { maxDepth: 0 }) {
      for (let i = 0, len = nodeList.length; i < len; i++) {
        const current = nodeList[i]
        if (current.depth > depthDesc.maxDepth) {
          depthDesc.maxDepth = current.depth
        }
        if (current.children) {
          this.getColMaxDepth(current.children, depthDesc)
        }
      }
      return depthDesc
    },

    /*
      + 每个节点的rowSpan、colSpan
    */
    nodeSpan(structure = []) {
      for (let i = 0, len = structure.length; i < len; i++) {
        const current = structure[i]
        if (current.children) {
          // 当前节包含的层级
          const hasRowSpan = this.getHasRowSpan(current.children, 0).maxDepth + 1
          current.hasRowSpan = hasRowSpan
          const colSpanDesc = this.colSpan(current.children)
          current.colSpan = colSpanDesc.colSpan
          this.nodeSpan(current.children)
        } else {
          current.hasRowSpan = 1
          current.colSpan = 1
        }
      }
    },

    /*
      + 当前节点实际掌控的row span
    */
    getHasRowSpan(nodeList, parentDepth = 0, nodeDesc = { maxDepth: 0 }) {
      for (let i = 0, len = nodeList.length; i < len; i++) {
        const current = nodeList[i]
        const depthTemp = parentDepth + 1
        if (depthTemp > nodeDesc.maxDepth) {
          nodeDesc.maxDepth = depthTemp
        }
        if (current.children) {
          this.getHasRowSpan(current.children, depthTemp, nodeDesc)
        }
      }

      return nodeDesc
    },

    rowSpan(structure = [], restRow = 0) {
      for (let i = 0, len = structure.length; i < len; i++) {
        const current = structure[i]
        if (current.hasRowSpan === restRow) {
          if (current.children) {
            current.rowSpan = 1
            this.rowSpan(current.children, restRow - 1)
          } else {
            current.rowSpan = restRow
          }
        } else {
          current.rowSpan = restRow
        }
      }
    },

    colSpan(nodeList, nodeDesc = { colSpan: 0 }) {
      for (let i = 0, len = nodeList.length; i < len; i++) {
        const current = nodeList[i]
        if (current.children) {
          this.colSpan(current.children, nodeDesc)
        } else {
          nodeDesc.colSpan = nodeDesc.colSpan + 1
        }
      }
      return nodeDesc
    },

    /*
      + 底层数据
    */
    getBottomList(structure = [], result = []) {
      for (let i = 0, len = structure.length; i < len; i++) {
        const current = structure[i]
        if (current.children) {
          this.getBottomList(current.children, result)
        } else {
          // result.push({ ...current, width: current.width ? current.width : 180 });
          result.push(current)
        }
      }
      return result
    }
  }
}
</script>
<style>
.table-tempalte {
  display: none;
}
</style>
